package com.shizhi.usp.base;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.os.EnvironmentCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.felhr.utils.HexData;
import com.hjlys.serialportlib.ByteUtils;
import com.shizhi.usp.R;
import com.shizhi.usp.serialport.SerialTestFra;
import com.shizhi.usp.setting.SettingsActivity;
import com.shizhi.usp.usb.UsbTestFra;
import com.shizhi.usp.util.PacketTestHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;

/**
 * @author Created by Administrator on  2018-01-16
 * @version 1.0.
 */

public abstract class BaseSerialFra extends Fragment implements SerialListener {
    private static final String TAG = "BaseSerialAct";
    @BindView(R.id.open)
    ToggleButton mOpen;
    @BindView(R.id.send_info)
    EditText mSendInfo;
    @BindView(R.id.send)
    Button mSend;

    @BindView(R.id.clear_info)
    Button mClearInfo;
    @BindView(R.id.settings)
    Button mSettings;
    @BindView(R.id.receiver_info)
    TextView mReceiverInfo;
    @BindView(R.id.cbAutoSend)
    CheckBox mCheckBoxAutoSend;
    @BindView(R.id.checkbox_addEnter)
    CheckBox mCheckBoxAddEnter;
    @BindView(R.id.checkbox_addLines)
    CheckBox mCheckBoxAddLines;
    @BindView(R.id.send_type)
    CheckBox mCheckBoxSendType;
    @BindView(R.id.btnUpFile)
    Button mBtnUpFile;
    @BindView(R.id.et_path)
    EditText mEtPath;
    @BindView(R.id.checkboxOutLocal)
    CheckBox mCheckBoxOutLocal;

    public UsbManager mUsbManager;
    private Unbinder unbinder;
    protected boolean isHex = true;
    protected boolean isOutLocal = true;
    public Activity mActivity;
    private int line0 = 0;
    private MainHandler mMainHandler;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivity = getActivity();
        mUsbManager = ((UsbManager) mActivity.getSystemService(Context.USB_SERVICE));
        mMainHandler = new MainHandler();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View inflate = inflater.inflate(R.layout.activity_main, container, false);
        unbinder = ButterKnife.bind(this, inflate);
        return inflate;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mOpen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    openSerial();
                } else {
                    closeSerial();
                }
            }
        });
        isOutLocal = mCheckBoxOutLocal.isChecked();
        mCheckBoxOutLocal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isOutLocal = isChecked;
            }
        });
        mBtnUpFile.setOnClickListener(v -> {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String pathname = Environment.getExternalStorageDirectory().getAbsolutePath() + mEtPath.getText().toString().trim();
                    File file = new File(pathname);
                    FileInputStream inputStream = null;
                    int allLne = 0;
                    try {
                        inputStream = new FileInputStream(file.getAbsolutePath());
                        byte[] data = new byte[30];
                        int readLen = 0;
                        while (true) {
                            readLen = inputStream.read(data);
                            if (readLen > 0) {
                                allLne += readLen;
                                writeData(data, 0, readLen);
                                //Thread.sleep(50);
                            } else {
                                break;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (inputStream != null) {
                            try {
                                inputStream.close();
                                inputStream = null;
                            } catch (IOException e) {
                                //
                            }
                        }
                    }
                    Message message = mMainHandler.obtainMessage();
                    message.arg1 = 3;
                    message.obj = "传输完成" + allLne;
                    message.sendToTarget();
                    Looper.prepare();
                    Toast.makeText(mActivity, "传输完成", Toast.LENGTH_SHORT).show();
                    Looper.loop();
                }
            }).start();
        });
        mCheckBoxSendType.setOnCheckedChangeListener((buttonView, isChecked) -> isHex = isChecked);
        isHex = mCheckBoxSendType.isChecked();

        mCheckBoxAutoSend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            private Thread autoSendTask;

            final class AutoSendTask extends Thread {
                @Override
                public void run() {
                    while (!Thread.currentThread().isInterrupted()) {
                        String sendData = mSendInfo.getText().toString();
                        if (!TextUtils.isEmpty(sendData)) {
                            byte[] data;
                            if (isHex) {
                                data = HexData.stringTobytes(sendData);
                            } else {
                                StringBuilder builder = new StringBuilder();
                                builder.append(sendData);
                                if (mCheckBoxAddLines.isChecked()) {
                                    if (line0 > 100) line0 = 0;
                                    builder.append(String.valueOf(line0++));
                                }
                                if (mCheckBoxAddEnter.isChecked()) {
                                    builder.append("\n");
                                }
                                data = builder.toString().getBytes();
                            }
                            writeData(data);
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
//                        try {
//                            Thread.sleep(100);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                            break;
//                        }
                    }
                }
            }


            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    if (autoSendTask == null) {
                        autoSendTask = new AutoSendTask();
                        autoSendTask.start();
                    }
                } else {
                    if (autoSendTask != null) {
                        autoSendTask.interrupt();
                        autoSendTask = null;
                    }
                }
            }
        });

        if (this instanceof UsbTestFra) {
            mSendInfo.setText("555500000003010301");
        } else {
//            mSendInfo.setText("FE0D001001070000000101000128FF");
            //LED
//            mSendInfo.setText("5AA500325201010000000001121231080808001CB0AEC9FABBEEB0AEC0ADB7BCA3ACC5C2C9CFBBF0BAC8CDF5C0CFBCAA4FB8");
            mSendInfo.setText("0D0AFA010201FB0D0A");
        }
    }


    @Override
    public void onDestroyView() {
        unbinder.unbind();
        closeSerial();
        super.onDestroyView();
    }


    @OnClick({R.id.settings, R.id.send, R.id.clear_info})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.settings:
                initSerial();
                break;
            case R.id.send:
                String trim = mSendInfo.getText().toString();
                if (TextUtils.isEmpty(trim)) return;
                try {
                    byte[] data;
                    if (isHex) {
                        data = HexData.stringTobytes(trim);
                    } else {
                        StringBuilder builder = new StringBuilder();
                        builder.append(trim);
                        if (mCheckBoxAddLines.isChecked()) {
                            if (line0 > 100) line0 = 0;
                            builder.append(String.valueOf(line0++));
                        }
                        if (mCheckBoxAddEnter.isChecked()) {
                            builder.append("\n");
                        }
                        data = builder.toString().getBytes();
                    }
                    writeData(data);
                } catch (Exception e) {
                    Toast.makeText(mActivity, "格式错误", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.clear_info:
                mReceiverInfo.setText("");
                break;
        }
    }

    @Override
    public void initSerial() {
        Intent intent = new Intent(mActivity, SettingsActivity.class);
        intent.putExtra("activity", this.getClass().getName());
        startActivity(intent);
    }

    @Override
    public void receiverData(byte[] data) {
        String s;
        if (isHex) {
            s = ByteUtils.bytesToHexString(data);
        } else {
            s = new String(data);
        }
        Message message = mMainHandler.obtainMessage();
        message.arg1 = 1;
        message.obj = s;
        message.sendToTarget();
    }

    public void receiverData(String data) {
        Message message = mMainHandler.obtainMessage();
        message.arg1 = 1;
        message.obj = data;
        message.sendToTarget();
    }

    @Override
    public void onStatuChanged(String data) {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mReceiverInfo.setText("");
                mReceiverInfo.append(data);
            }
        });
    }

    /**
     * @return port info
     */
    public String[] getSerialPort() {
        String name;
        int braunter, data, stop, parity;
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mActivity);
        name = sharedPreferences.getString("name", "");
        braunter = Integer.valueOf(sharedPreferences.getString("braunte", "-1"));
        data = Integer.valueOf(sharedPreferences.getString("data", "-1"));
        stop = Integer.valueOf(sharedPreferences.getString("stop", "-1"));
        parity = Integer.valueOf(sharedPreferences.getString("parity", "-1"));
        Log.d(TAG, String.format("info: name:%s braunter:%s data:%s stop:%s parity:%s", name, braunter, data, stop, parity));
        if (!TextUtils.isEmpty(name) || braunter != -1 || data != -1 || stop != -1 || parity != -1) {
            String[] strings = {name, String.valueOf(braunter), String.valueOf(data), String.valueOf(stop), String.valueOf(parity)};
            Log.d(TAG, "getSerialPort: " + Arrays.toString(strings));
            return strings;
        }
        return null;
    }

    private final class MainHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int lineCount = 0;
            switch (msg.arg1) {
                case 1:
                    lineCount = mReceiverInfo.getLineCount();
                    if (lineCount > 1000) mReceiverInfo.setText("");
                    mReceiverInfo.append(msg.obj + "");

                    int offset = mReceiverInfo.getLineCount() * mReceiverInfo.getLineHeight();
                    if (offset > mReceiverInfo.getHeight()) {
                        mReceiverInfo.scrollTo(0, offset - mReceiverInfo.getHeight());
                    }
                    break;
                case 3:
                    mReceiverInfo.setText(msg.obj.toString());
                    break;

            }
        }
    }
}
